/*
Reverse a linked list from position m to n. Do it in-place and in one-pass.

For example:
Given 1->2->3->4->5->NULL, m = 2 and n = 4,

return 1->4->3->2->5->NULL.

Note:
Given m, n satisfy the following condition:
1 ≤ m ≤ n ≤ length of list.
*/

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *reverseBetween(ListNode *head, int m, int n) {
        if (!head || m==n) return head;
        ListNode *prev = NULL, *cur = head;
        while (--m) {
            prev = cur;
            cur = prev->next;
            n--;
        }
        ListNode *first = prev;
        ListNode *begin = cur;
        while (n-- && cur) {
            // reverse two nodes
            ListNode *next = cur->next;
            cur->next = prev;
            prev = cur;
            cur = next;
        }
        // connect begin and end blocks
        begin->next = cur;
        if (first) first->next = prev;
        else head = prev; // m = 1
        return head;
    }
};
